/*****************************************************************************/
/**
 *  @file   ParticleDraw.h
 *  @author Allan Lorant, Naohisa Sakamoto
 */
/*----------------------------------------------------------------------------
 *
 *  Copyright (c) Visualization Laboratory, Kyoto University.
 *  All rights reserved.
 *  See http://www.viz.media.kyoto-u.ac.jp/kvs/copyright/ for details.
 *
 *  $Id$
 */
/*****************************************************************************/
#ifndef PARTICLE_DRAW_H_INCLUDE
#define PARTICLE_DRAW_H_INCLUDE

#include <cstring>
#include <iostream>
#include <flowvr/module.h>
#include <flowvr/trace.h>
#include <ftl/chunkevents.h>
#include "InterfaceBase.h"


namespace ParticleDraw
{

class Interface : public InterfaceBase
{
private:

    flowvr::InputPort* m_particle_port;

public:

    Interface()
    {
        // Declare user defined ports :
        m_particle_port = new flowvr::InputPort( "particleIn" );

        std::vector<flowvr::Port*> ports;
        ports.push_back( m_particle_port );

        if ( InterfaceBase::init( ports ) )
        {
            std::cout << "Can't initialize flowVR module !" << std::endl;
        }
    }

    ~Interface()
    {
        if ( m_particle_port ) delete m_particle_port;
    }

    kvs::PointObject* recv()
    {
        if ( !InterfaceBase::wait() ) { return false; }

        // Read the data
        flowvr::Message particle;
        InterfaceBase::get( "particleIn", particle );

        // Copy the read data from the messages
        const kvs::UInt32 vert_size = ( sizeof(kvs::Real32)*2 + sizeof(kvs::UInt8) ) * 3;
        const kvs::UInt32 nverts = particle.data.getSize() / vert_size;
        kvs::ValueArray<kvs::Real32> coords( nverts * 3 );
        kvs::ValueArray<kvs::UInt8> colors( nverts * 3 );
        kvs::ValueArray<kvs::Real32> normals( nverts * 3 );

        const char* pcoords = particle.data.getRead<char>();
        const char* pcolors = pcoords + coords.byteSize();
        const char* pnormals = pcolors + colors.byteSize();
#if ( KVS_VERSION_MAJOR == 1 )
        std::memcpy( coords.pointer(), pcoords, coords.byteSize() );
        std::memcpy( colors.pointer(), pcolors, colors.byteSize() );
        std::memcpy( normals.pointer(), pnormals, normals.byteSize() );
#elif ( KVS_VERSION_MAJOR == 2 )
        std::memcpy( coords.data(), pcoords, coords.byteSize() );
        std::memcpy( colors.data(), pcolors, colors.byteSize() );
        std::memcpy( normals.data(), pnormals, normals.byteSize() );
#endif
        particle.data.clear();

        kvs::PointObject* object = new kvs::PointObject();
        object->setCoords( coords );
        object->setColors( colors );
        object->setNormals( normals );

        return object;
    }
};

} // end of namespace ParticleDraw

#endif // PARTICLE_DRAW_H_INCLUDE
